package cn.iocoder.yudao.module.xiaoBizHandler.service.tbFile;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.iocoder.yudao.framework.common.genId.PKGenerator;
import cn.iocoder.yudao.module.system.framework.attach.config.AttachProperties;
import cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.tbFile.vo.XTbFileCreateReqVO;
import cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.tbFile.vo.XTbFileExportReqVO;
import cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.tbFile.vo.XTbFilePageReqVO;
import cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.tbFile.vo.XTbFileUpdateReqVO;
import cn.iocoder.yudao.module.xiaoBizHandler.dal.dataobject.attach.AttachDO;
import cn.iocoder.yudao.module.xiaoBizHandler.service.attach.AttachService;
import cn.iocoder.yudao.module.xiaoBizHandler.utils.FileUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.TimeUnit;

import cn.iocoder.yudao.module.xiaoBizHandler.dal.dataobject.tbFile.XTbFileDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.xiaoBizHandler.convert.tbFile.XTbFileConvert;
import cn.iocoder.yudao.module.xiaoBizHandler.dal.mysql.tbFile.XTbFileMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.xiaoBizHandler.enums.ErrorCodeConstants.*;

/**
 * 文件 Service 实现类
 *
 * @author XiaoSiyuan
 */
@Service
@Validated
public class XTbFileServiceImpl implements XTbFileService {

    @Resource
    private XTbFileMapper xTbFileMapper;

    @Resource
    AttachProperties attachProperties;

    @Resource
    AttachService attachService;


    @Override
    public String createXTbFile(XTbFileCreateReqVO createReqVO) {
        // 插入
        XTbFileDO xTbFile = XTbFileConvert.INSTANCE.convert(createReqVO);
        xTbFile.setId(PKGenerator.newId());
        xTbFileMapper.insert(xTbFile);
        // 返回
        return xTbFile.getId();
    }

    @Override
    public void updateXTbFile(XTbFileUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateXTbFileExists(updateReqVO.getId());
        // 更新
        XTbFileDO updateObj = XTbFileConvert.INSTANCE.convert(updateReqVO);
        xTbFileMapper.updateById(updateObj);
    }

    @Override
    public void deleteXTbFile(String id) {
        // 校验存在
        this.validateXTbFileExists(id);
        // 删除
        xTbFileMapper.deleteById(id);
    }

    private void validateXTbFileExists(String id) {
        if (xTbFileMapper.selectById(id) == null) {
            throw exception(X_TB_FILE_NOT_EXISTS);
        }
    }

    @Override
    public XTbFileDO getXTbFile(String id) {
        return xTbFileMapper.selectById(id);
    }

    @Override
    public List<XTbFileDO> getXTbFileList(Collection<String> ids) {
        return xTbFileMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<XTbFileDO> getXTbFilePage(XTbFilePageReqVO pageReqVO) {
        PageResult<XTbFileDO> xTbFileDOPageResult = xTbFileMapper.selectPage(pageReqVO);
        return xTbFileDOPageResult;
    }

    @Override
    public List<XTbFileDO> getXTbFileList(XTbFileExportReqVO exportReqVO) {
        return xTbFileMapper.selectList(exportReqVO);
    }

    @Override
    public void openFile(String absolutePath) throws IOException {
        String batFileAbsPath = System.getProperty("java.io.tmpdir") + File.separator + PKGenerator.newId() + ".bat";
        File batFile = FileUtil.touch(batFileAbsPath);
        FileWriter fileWriter = FileWriter.create(batFile, StandardCharsets.UTF_8);
        fileWriter.write(absolutePath);
        try {
            Runtime.getRuntime().exec("cmd /c " + batFileAbsPath);
//            Runtime.getRuntime().exec("cmd.exe /c " + batFileAbsPath);
            // 关闭窗口用 /c
            // 不关闭用 /k
            // c close
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 文件的执行应该是异步执行，3s后再删执行文件
            ThreadUtil.sleep(3, TimeUnit.SECONDS);
            FileUtil.del(batFile);
        }
    }

    @Override
    public void refreshFile(String id) throws IOException {
        XTbFileDO xTbFile = getXTbFile(id);
        if (xTbFile == null)    return;
//        xTbFile.getFilePath()
    }


    /**
     * 创建文件
     * @param createReqVO
     * @return
     */
    public String createFile(XTbFileCreateReqVO createReqVO) {
        // 插入
        XTbFileDO xTbFile = XTbFileConvert.INSTANCE.convert(createReqVO);
        xTbFile.setId(PKGenerator.newId());
        // 复制附件，新增一条附件数据
        String basePath = ResourceUtil.getResource("").getPath();
        if (basePath.startsWith("/"))   basePath = basePath.substring(1);
        String xmindTmpFilePath = basePath + attachProperties.getXmindTmpFilePath();
        AttachDO attach = attachService.createAttach(xTbFile.getFileName(), xTbFile.getId(), xmindTmpFilePath);
        xTbFile.setFilePath(attach.getId());
        xTbFileMapper.insert(xTbFile);
       // 返回
        return xTbFile.getId();
    }

    /**
     * 创建并打开文件
     * @param createReqVO
     * @return
     */
    public String createAndOpenFile(XTbFileCreateReqVO createReqVO) throws IOException {
        // 插入
        XTbFileDO xTbFile = XTbFileConvert.INSTANCE.convert(createReqVO);
        xTbFile.setId(PKGenerator.newId());
        // 复制附件，新增一条附件数据
        String xmindTmpFilePath = ResourceUtil.getResource("").getPath() + attachProperties.getXmindTmpFilePath();
        AttachDO attach = attachService.createAttach(xTbFile.getFileName(), xTbFile.getId(), xmindTmpFilePath);
        String attachPath = attachService.getAttachPath(attach.getId());
        xTbFile.setFilePath(attach.getId());
        xTbFileMapper.insert(xTbFile);
        // 打开文件
        openFile(attachPath);
        // 返回
        return xTbFile.getId();
    }


}
